/*
 *  dna_profile.h -- provide dna-system profile simple wrap interface.
 *  
 *  ORIGINAL AUTHOR: Xu Chun (chun.xu@broadlink.com.cn)
 *
 *  Copyright (c) 2016 Broadlink Corporation
 */

#ifndef __DNA_PROFILE_H
#define __DNA_PROFILE_H

#define DNA_PROFILE_INIT_MAGIC                      (('P' << 0)|('R' << 8)|('O' << 16)|('F' << 24))
#define DNA_DEVICE_NAME_MAX_LEN                     64
#define DNA_DEVICE_PID_MAX_LEN                      16
#define DNA_DEVICE_SUBTYPE_LEN                      16
#define DNA_CLOUD_PLATFORM_MAX_CNT                  32

/* The special command type code defined in profile */
enum {
    /* WiFi module network state active notice */
	DNA_MODULE_CONFIG_RES           =  0,
    DNA_MODULE_CONNECTING_RES,
    DNA_MODULE_WIFI_LINK_RES,
    DNA_MODULE_CLOUD_LINK_RES, // 3
    /* Heartbeat (module active) */
	DNA_MODULE_TO_BOARD_HB_REQ,
	DNA_MODULE_TO_BOARD_HB_RES,
	/* Module reply to device when device active post */
	DNA_ACTIVE_POST_RES,
	/* Query device status command1 */
	DNA_BOARD_STATUS_REQ1,
	/* Query device status command2 */
	DNA_BOARD_STATUS_REQ2,
	/* Module time request */
	DNA_MODULE_TIME_REQ, // 9
	/* Module firmware info request */
	DNA_MODULE_FIRMWARE_REQ, // 10
	/* Module reset request */
    DNA_MODULE_RST_REQ, // 11
    /* Module reset response */
	DNA_MODULE_RST_RES, // 12
	/* Module entry test mode request */
    DNA_MODULE_ENTRY_TEST_REQ,
    /* Module entry test mode response */
    DNA_MODULE_ENTRY_TEST_RES,
    /* Heartbeat (device active) */
    DNA_BOARD_TO_MODULE_HB_REQ,
    DNA_BOARD_TO_MODULE_HB_RES,
    /* Module WLAN scan result request */
    DNA_MODULE_SSID_LIST_REQ,
    /* Module WLAN scan result response */
    DNA_MODULE_SSID_LIST_RES,
    /* Query device type request */
    DNA_BOARD_DEVTYPE_REQ,
    /* Module erase (format) request */
    DNA_MODULE_ERASE_REQ, // 20
    /* Module erase (format) response */
    DNA_MODULE_ERASE_RES, // 21
    /* Module AirConfig complete notice */
    DNA_MODULE_AIRCFG_NOTICE,
    /* Module Get Mac request */
    DNA_MODULE_GET_MAC_REQ,
    /*Module enrty ap req*/
	DNA_MODULE_ENTRY_AP_REQ,
	/*Module enrty ap rsp*/
	DNA_MODULE_ENTRY_AP_RES,
	/*Module Get Wlan Info req*/
	DNA_MODULE_WLANINFO_REQ,
	/* Module suspend request (module -> device) */
	DNA_MODULE_SUSPEND_REQ,
	/* Module suspend response (device -> module) */
	DNA_MODULE_SUSPEND_RES,
	/* Module audio channel ON/OFF response (module -> device) */
    DNA_MODULE_AUDIO_CHANNEL_RES,
    /* Module fastcon autojoin enable */
    DNA_MODULE_FC_AUTOJOIN_REQ, // 30
    DNA_MODULE_FC_AUTOJOIN_RSP, // 31
    /* Limits */
    DNA_SPECIAL_CMD_TYPE_MAX,
};

/* dna-system profile header information (128Bytes) */
typedef DNA_PACKED_START struct dna_profile_hdr {
    unsigned char platform[3];
    unsigned int length;
    unsigned char type;
    struct {
        unsigned int magic;
        unsigned int cfg_file_ver;
        unsigned int hw_lowest_ver;
        unsigned int checksum;
    } info;
    unsigned char md5[16];
    unsigned char pad[88];
} DNA_PACKED_END dna_profile_hdr_t;

/* dna-system product information */
typedef struct dna_device_info {
    unsigned int profile_version;
    char name[DNA_DEVICE_NAME_MAX_LEN];
    unsigned char pid[DNA_DEVICE_PID_MAX_LEN];
    /* Cloud platform mask and mode mask code */
    unsigned int mask;
    unsigned int mode_mask[DNA_CLOUD_PLATFORM_MAX_CNT >> 4];
    unsigned int subtype_enable         : 1;
    unsigned int ota_enable             : 1;
    unsigned int cloud_menu_enable      : 1;
    unsigned int period_upload_enable   : 1;
    unsigned int trigger_upload_enable  : 1;
    unsigned int active_upload_enable   : 1;
    unsigned long snapshot_refresh_freq;
    unsigned long period_upload_freq;
    unsigned long trigger_upload_freq;
    unsigned short netstate_notice_freq;
    unsigned short heartbeat_freq;
    unsigned short netcfg_timeout;
    unsigned short chip_type;
    char subtype[DNA_DEVICE_SUBTYPE_LEN];
	int netcfg_mode;
} dna_device_info_t;

/* dna-system special command index information */
typedef struct dna_special_cmd_info {
    unsigned short len;
    unsigned short offset;
} dna_special_cmd_info_t;

/* dna-system special command sets index table */
typedef struct dna_special_cmd_sets {
    unsigned int count;
    dna_special_cmd_info_t data_entry[DNA_SPECIAL_CMD_MAX_CNT];
    dna_special_cmd_info_t mask_entry[DNA_SPECIAL_CMD_MAX_CNT];
    /* data pool */
    unsigned char * data;
    unsigned char * mask_data;
} dna_special_cmd_sets_t;

/* dna-system profile data descriptor */
typedef struct dna_profile_data {
    unsigned int init;
    dna_device_info_t info;
    dna_special_cmd_sets_t cmd_table;
    unsigned char cmd_data[DNA_SPECIAL_CMD_BUFF_SIZE];
    unsigned char cmd_mask_data[DNA_SPECIAL_CMD_BUFF_SIZE];
    unsigned short active_data_len;
    unsigned short active_mask_len;
    unsigned char active_data[DNA_SPECIAL_CMD_MAX_LEN];
    unsigned char active_mask[DNA_SPECIAL_CMD_MAX_LEN];
} dna_profile_data_t;

/*
*  dna-system data compare interface.
*
*  @input1: input data1
*  @input2: input data2
*  @mask: mask code
*  @len: input data valid length
*  @mask_len: mask code valid length
*
*   Return TRUE means input1 and input2 match success.
*/
int dna_data_compare(
         const unsigned char * input1, const unsigned char * input2,
         const unsigned char * mask, unsigned int len, unsigned int mask_len);

/*
*  dna-system get binary value according to the start bit and end bit.
*
*  @input: input data
*  @start_bit: start position
*  @end_bit: end position
*  @value: output param, raw data
*
*  Notice: now only support little-endian.
*/
void dna_get_binary_value(
          const unsigned char * input, unsigned int start_bit,
          unsigned int end_bit, unsigned int * value);

/*
*  dna-system set binary value according to the start bit and end bit.
*
*  @input: input data
*  @start_bit: start position
*  @end_bit: end position
*  @value: input param, raw data
*
*  Notice: now only support little-endian.
*/
void dna_set_binary_value(
       unsigned char * input, unsigned int start_bit,
       unsigned int end_bit, unsigned int * value);

/*
*  dna-system get special command data based on index.
*
*  @profile: device profile
*  @index: command index
*  @buffer: command data buffer
*  @size: command data buffer maxsize
*
*  Return command data valid length.
*/
int dna_profile_special_cmd_get(
         dna_profile_data_t * profile, unsigned int index,
         unsigned char * buffer, unsigned int size);

/*
*  dna-system special command data match.
*
*  @profile: device profile
*  @input: input data
*  @len: input data length
*
*  Return command index when match success.
*/
int dna_profile_special_cmd_match(
         dna_profile_data_t * profile,
         const unsigned char * input, unsigned int len);

/*
*  dna-system active upload data match.
*
*  @profile: device profile
*  @input: input data
*  @len: input data length
*
*  Return TRUE when match success.
*/
int dna_profile_active_upload_match(
         dna_profile_data_t * profile,
         const unsigned char * input, unsigned int len);

/*
*  dna-system profile header information get interface.
*
*  Return 0 means get success.
*/
int dna_profile_header_info(dna_profile_hdr_t * header);

/*
*  dna-system profile verify check interface.
*
*  Return TRUE means verify check success.
*/
int dna_profile_check(void);

#ifdef CONFIG_SUPPORT_DNA_GATEWAY
void dna_profile_cfg_pid(unsigned char pid[16]);
#endif

/*
*  dna-system profile data load interface.
*
*  @profile: device profile
*
*  Return 0 when load success.
*/
int dna_profile_data_load(dna_profile_data_t * profile);

/*
*  dna-system profile data unload interface.
*
*  @profile: device profile
*
*  Return 0 when unload success.
*/
int dna_profile_data_unload(dna_profile_data_t * profile);

/*
*  dna-system profile device basic information get interface.
*
*  @profile: device profile
*
*  Notice: please call this interface to get devinfo, don't quote directly through profile structure.
*
*  Return NULL means device not ready.
*/
dna_device_info_t * dna_profile_get_devinfo(dna_profile_data_t * profile);

/*
*  dna-system profile device basic information dump interface.
*  It used for debug.
*
*  @profile: device profile
*/
void dna_profile_devinfo_dump(dna_profile_data_t * profile);

/*
*  dna-system generate AirConfig rework SSID basend on profile.
*
*  Return rework SSID.
*/
const char * dna_profile_aircfg_rework_ssid(void);


#endif

